package com.vpen.client.stomp;

import cn.hutool.json.JSONUtil;
import com.vpen.client.test.MyListenableFutureCallback;
import com.vpen.client.test.MyStompSessionHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.converter.CompositeMessageConverter;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.messaging.converter.StringMessageConverter;
import org.springframework.messaging.simp.stomp.StompHeaders;
import org.springframework.messaging.simp.stomp.StompSession;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.stereotype.Component;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHttpHeaders;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
import org.springframework.web.socket.messaging.WebSocketStompClient;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

/**
 * 描述
 *
 * @author 韦鹏
 * @date 2022/11/28 21:56
 */
@Slf4j
@Component
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class StompWebsocketClient {
    public static final String URL = "ws://localhost:8000/chat-endpoint";

    private final TaskScheduler taskScheduler;
    private final ClientStompSessionHandler clientStompSessionHandler;

    private StompSession stompSession;


    /**
     * 连接服务器
     */
    public StompSession connect() throws ExecutionException, InterruptedException {
        // 创建客户端
        StandardWebSocketClient standardWebSocketClient = new StandardWebSocketClient();
        // 创建Stomp客户端
        WebSocketStompClient socketStompClient = new WebSocketStompClient(standardWebSocketClient);
        /**
         * 使用多种消息转换器
         * */
        List<MessageConverter> converters = new ArrayList<>();
        converters.add(new MappingJackson2MessageConverter());
        converters.add(new StringMessageConverter());
        // 设置消息转换器
        socketStompClient.setMessageConverter(new CompositeMessageConverter(converters));

        // 设置定时线程池
        socketStompClient.setTaskScheduler(taskScheduler);

        // 握手用到的headers
        WebSocketHttpHeaders handshakeHeaders = new WebSocketHttpHeaders();
        handshakeHeaders.add("IP", "192.168.0.1");

        // stomp连接用到的headers，可以放token
        StompHeaders connectHeaders = new StompHeaders();
        connectHeaders.add("name", "vpen");


        // 连接websocket服务器
        ListenableFuture<StompSession> future = socketStompClient.connect(URL, handshakeHeaders, connectHeaders, clientStompSessionHandler);

        // 回调方法
        future.addCallback(new MyListenableFutureCallback());
        stompSession = future.get();
        stompSession.setAutoReceipt(true);
        return stompSession;
    }


    /**
     * 断开连接
     */
    public void disconnect() {
        if (null != this.stompSession) {
            this.stompSession.disconnect();
        }
    }

    /**
     * 发送消息
     */
    public void send(String destination, Object message) {
        getSession().send(destination, message);
    }

    /**
     * 订阅
     */
    public void subscribe(String destination) {
        getSession().subscribe(destination, clientStompSessionHandler);
    }


    public StompSession getSession() {
        // 如果为空，重连
        if (null == this.stompSession) {
            try {
                connect();
            } catch (ExecutionException | InterruptedException e) {
                log.error("连接失败");
                throw new RuntimeException(e);
            }
        }
        return this.stompSession;
    }


}
